#include <WifiUpgrade.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <fcntl.h>
#include <unistd.h>
#include "log_err.h"
#include "sign_kernel.h"

static const char* APP_PATH = "app_download.tar.gz";

WifiUpgrade* WifiUpgrade::instance = nullptr;

WifiUpgrade* WifiUpgrade::getInstance() 
{
    if (instance == nullptr) {
        instance = new WifiUpgrade();
    }
    return instance;
}

WifiUpgrade::WifiUpgrade(/* args */)
{
}

WifiUpgrade::~WifiUpgrade()
{
}

void WifiUpgrade::startUpgrade()
{
    SIGNWAY_LOGI("下载app.tar.gz 到 /tmp");
    app_fd = open(APP_PATH, O_CREAT | O_RDWR | O_SYNC | O_TRUNC);
}

uint32_t WifiUpgrade::download(uint8_t* buf, uint32_t len)
{
    int ret = 0;
    if (app_fd >= 0) {
        ret = write(app_fd, buf, len);
        if (ret < 0) {
            SIGNWAY_LOGE("write failed");
        }
    }
    return ret;
}

void WifiUpgrade::downloadFinished()
{
    close(app_fd);
    app_fd = -1;
    std::string cmd = "chmod 644 ";
    cmd += APP_PATH;
    system(cmd.c_str());
}

void WifiUpgrade::stopUpgrade()
{
    close(app_fd);
    app_fd = -1;
}

bool WifiUpgrade::check()
{
    SIGNWAY_LOGI("校验");
    return true;
}

void WifiUpgrade::upgrade()
{
    system("chmod +x ./wifi_upgrade.sh && ./wifi_upgrade.sh");
}

void WifiUpgrade::test(void)
{
    int fd = 0;
    int len = 0;
    bool ret = false;
    uint8_t buf[1024] = { 0 };
    const char* filename = "app.tar.gz";
    WifiUpgrade::getInstance()->startUpgrade();

    fd = open(filename, O_RDWR);
    SIGNWAY_ERROR_GOTO(fd < 0, RETURN, "%s open failed", filename);

    while (true) {
        bzero(buf, sizeof(buf));
        len = read(fd, buf, sizeof(buf));
        SIGNWAY_ERROR_GOTO(len < 0, RETURN, "%s read failed", filename);
        if (len == 0) {
            break;
        }
        WifiUpgrade::getInstance()->download(buf, len);
    }
    ret = true;

    WifiUpgrade::getInstance()->downloadFinished();
RETURN:
    if (fd >= 0) {
        close(fd);
    }
    return;
}
